package com.ztesoft.report.utils.ftp;

import com.jcraft.jsch.*;
import com.ztesoft.report.base.pojo.R;
import com.ztesoft.report.exception.FtpException;
import com.ztesoft.report.exception.RException;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

/**
 * Sftp客户端
 *
 * @author y3tu
 * @date 2018/4/9
 */
@Slf4j
public class SftpClient {
    private Session session = null;
    private ChannelSftp channel = null;

    private SftpClient() {
    }

    /**
     * 获取配置的默认连接
     *
     * @return
     * @throws FtpException
     */
//    public static SftpClient connectDefault() throws FtpException {
//        String host = PropertiesUtil.getString("sftp.host");
//        int port = PropertiesUtil.getInt("sftp.port");
//        String userName = PropertiesUtil.getString("sftp.user.name");
//        String password = PropertiesUtil.getString("sftp.user.password");
//        int timeout = PropertiesUtil.getInt("sftp.timeout");
//        int aliveMax = PropertiesUtil.getInt("sftp.aliveMax");
//        return new SftpClient().init(host, port, userName, password, timeout, aliveMax);
//    }

    /**
     * 获取sftp连接客户端
     *
     * @param host
     * @param port
     * @param userName
     * @param password
     * @param timeout
     * @param aliveMax
     * @return
     * @throws FtpException
     */
    public static SftpClient connect(String host, int port, String userName, String password, int timeout, int aliveMax) throws FtpException {
        return new SftpClient().init(host, port, userName, password, timeout, aliveMax);
    }

    public SftpClient init(String host, int port, String userName, String password, int timeout, int aliveMax) throws FtpException {
        try {
            Properties config = new Properties();

            // 创建JSch对象
            JSch jsch = new JSch();
            // 根据用户名，主机ip，端口获取一个Session对象
            session = jsch.getSession(userName, host, port);
            if (password != null) {
                // 设置密码
                session.setPassword(password);
            }
            config.put("userauth.gssapi-with-mic", "no");
            config.put("StrictHostKeyChecking", "no");
            // 为Session对象设置properties
            session.setConfig(config);
            // 设置timeout时间
            session.setTimeout(timeout);
            session.setServerAliveCountMax(aliveMax);
            // 通过Session建立链接
            session.connect();
            // 打开SFTP通道
            channel = (ChannelSftp) session.openChannel("sftp");
            channel.connect(); // 建立SFTP通道的连接
            log.info("SSH Channel connected.");
        } catch (JSchException e) {
            throw new FtpException("", e);
        }
        return this;
    }

    public void disconnect() {
        if (channel != null) {
            channel.disconnect();
        }
        if (session != null) {
            session.disconnect();
            log.info("SSH Channel disconnected.");
        }
    }
    /**
     * 获取文件名以及属性
     * @param path 文件获取路径
     * @Param suffix 获取文件名的后缀，以,隔开
     * @return list<map>
     *     map 含有2个属性 attr为文件属性，name 为文件名
     */
    public List<Map<String,Object>> getSftpFile(String path,String suffix) throws FtpException{
        List<Map<String,Object>> list = new ArrayList<>();
        try {
            Vector vector = channel.ls(path);
            for(Object obj :vector){
                if(obj instanceof com.jcraft.jsch.ChannelSftp.LsEntry){
                    SftpATTRS s= ((com.jcraft.jsch.ChannelSftp.LsEntry)obj).getAttrs();
                    String filename = ((com.jcraft.jsch.ChannelSftp.LsEntry)obj).getFilename();
                    if (!s.isDir() && suffix.toLowerCase().contains(filename.substring(filename.indexOf(".")+1).toLowerCase())) {
                        Map<String,Object> map = new HashMap<>();
                        map.put("attr", s);
                        map.put("name", filename);
                        list.add(map);
                    }
                }
            }
        } catch (SftpException e) {
            throw new FtpException("获取文件名称失败", e);
        }
        return list;
    }

    /**
     * 发送文件
     *
     * @param src 本地服务器文件目录地址
     * @param dst 远程文件目录地址
     */
    public void put(String src, String dst) throws FtpException {
        try {
            channel.put(src, dst, new FileProgressMonitor());
        } catch (SftpException e) {
            throw new FtpException("", e);
        }
    }

    /**
     * 获取文件
     *
     * @param src 远程文件目录地址
     * @param dst 本地服务器文件目录地址
     */
    public void get(String src, String dst) throws FtpException {
        try {
            channel.get(src, dst, new FileProgressMonitor());

        } catch (SftpException e) {
            throw new FtpException("", e);
        }
    }

    /**
     * 创建一个文件目录
     */
    public void createDir(String createpath) throws Exception {
        try {
            if (isDirExist(createpath)) {
                channel.cd(createpath);
                return;
            }
            String pathArry[] = createpath.split("/");
            StringBuffer filePath = new StringBuffer("/");
            for (String path : pathArry) {
                if (path.equals("")) {
                    continue;
                }
                filePath.append(path + "/");
                if (isDirExist(path)) {
                    channel.cd(path);
                } else {
                    // 建立目录
                    channel.mkdir(path);
                    log.info("建立目录："+path);
                    // 进入并设置为当前目录
                    channel.cd(path);
                }
            }
            this.channel.cd("/");
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("创建路径错误：" + createpath);
        }
    }

    /**
     * 判断目录是否存在
     */
    public boolean isDirExist(String directory) {
        boolean isDirExistFlag = false;
        try {
            SftpATTRS sftpATTRS = channel.lstat(directory);
            isDirExistFlag = true;
            return sftpATTRS.isDir();
        } catch (Exception e) {
            if (e.getMessage().toLowerCase().equals("no such file")) {
                isDirExistFlag = false;
            }
        }
        return isDirExistFlag;
    }
    /**
     * 删除一个文件
     */
    public void deleteFile(String fileUrl) {
        try {
            channel.rm(fileUrl);
            log.info("删除文件成功："+fileUrl);
        } catch (SftpException e) {
            e.printStackTrace();
            log.info("删除文件失败："+fileUrl);
        }
    }

    /**
     * 测试
     *
     * @param args
     */
    public static void main(String[] args) {
        String host = "45.40.206.202";
        int port = 22;
        String userName = "root";
        String password = "Cjf.1996515";
        int timeout = 2000;
        int aliveMax = 2000;
        try {
            SftpClient sftpClient = SftpClient.connect(host, port, userName, password, timeout, aliveMax);
            System.out.println("连接成功");
/*            sftpClient.put("C:\\Users\\ASUS\\Desktop\\tempexcel.xls","/home/cjf");
            sftpClient.deleteFile("/home/cjf/tempexcel.xls");*/
            sftpClient.disconnect();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
